package jl.com.util;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ImgUtil {
    /**
     * 链接url下载图片
     * 注：path 路径一定要先有个图片用来被替换,如用时间戳命名则不需要
     * 如：img/" + System.currentTimeMillis() + ".png
     *
     * @param urlList
     * @param path
     */
    public static void downloadPicture(String urlList, String path) {
        URL url = null;
        try {
            url = new URL(urlList);
            DataInputStream dataInputStream = new DataInputStream(url.openStream());

            FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int length;

            while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            fileOutputStream.write(output.toByteArray());
            dataInputStream.close();
            fileOutputStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 链接url下载图片
     * 注：path 路径一定要先有个图片用来被替换
     *
     * @param urlImg
     * @param path
     * @throws Exception
     */
    public static void newImg(String urlImg, String path) throws Exception {
        //new一个URL对象
        URL url = new URL(urlImg);
        //打开链接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置请求方式为"GET"
        conn.setRequestMethod("GET");
        //超时响应时间为5秒
        conn.setConnectTimeout(5 * 1000);
        //通过输入流获取图片数据
        InputStream inStream = conn.getInputStream();
        //得到图片的二进制数据，以二进制封装得到数据，具有通用性
        byte[] data = readInputStream(inStream);
        //new一个文件对象用来保存图片，默认保存当前工程根目录
        File imageFile = new File(path);
        //创建输出流
        FileOutputStream outStream = new FileOutputStream(imageFile);
        //写入数据
        outStream.write(data);
        //关闭输出流
        outStream.close();
    }

    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

    /**
     * 截图+定位，下载图片
     *
     * @param element
     * @return
     * @throws Exception
     */
    public static byte[] captureElement(WebElement element) throws Exception {
        WrapsDriver wrapsDriver = (WrapsDriver) element;
        // 截图整个页面
        byte[] screen = ((TakesScreenshot) wrapsDriver.getWrappedDriver()).getScreenshotAs(OutputType.BYTES);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            BufferedImage img = ImageIO.read(new ByteArrayInputStream(screen));
            ImageIO.write(img, "png", new File("img/imgs/img" + System.currentTimeMillis() + ".png"));

            // 获得元素的高度和宽度
            int width = element.getSize().getWidth();
            int height = element.getSize().getHeight();
            // 创建一个矩形使用上面的高度，和宽度
            java.awt.Rectangle rect = new java.awt.Rectangle(width, height);
            // 得到元素的坐标
            Point p = element.getLocation();

            float rate = img.getWidth() / 1024;
            BufferedImage dest = img.getSubimage(
                    (int) (p.getX() * rate),
                    (int) (p.getY() * rate),
                    (int) (rect.width * rate), (int) (rect.height * rate));
            ImageIO.write(dest, "png", new File("img/" + System.currentTimeMillis() + ".png"));
            boolean flag = ImageIO.write(dest, "png", out);
            byte[] imageData = out.toByteArray();
            return imageData;
        } finally {
            out.close();
        }
    }

    /**
     * 截图+定位，下载图片
     *
     * @param driver
     * @param element
     * @throws Exception
     */
    public static void shootWebElement(WebDriver driver, WebElement element) throws Exception {
        File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//截图
        Point p = element.getLocation();
        int width = element.getSize().getWidth();
        int height = element.getSize().getHeight();
        System.out.println("width:" + width);
        System.out.println("height:" + height);
        System.out.println("p.getX():" + p.getX());
        System.out.println("p.getY():" + p.getY());
        BufferedImage img = ImageIO.read(screen);
        BufferedImage dest = img.getSubimage(p.getX(), p.getY(), width, height);//x = width, y = height
        ImageIO.write(dest, "png", screen);
        File f = new File("img/" + System.currentTimeMillis() + ".png");
        FileUtils.copyFile(screen, f);
    }

    /**
     * @Description： 图片转化成base64字符串
     *
     * @param: path
     * @Return:
     */
    public static String GetImageStr1(String path) {
        // 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        // 待处理的图片
        String imgFile = path;
        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回Base64编码过的字节数组字符串
        return encoder.encode(data);
    }

    /**
     * 将网络图片转成Base64码，此方法可以解决解码后图片显示不完整的问题
     * （加上data:image/jpeg;base64,）
     * @param "imgURL图片地址。 例如：http://***.com/271025191524034.jpg
     * @return
     */
    public static String imgBase64(String imgURL) {
        ByteArrayOutputStream outPut = new ByteArrayOutputStream();
        byte[] data = new byte[1024];
        try {
            // 创建URL
            URL url = new URL(imgURL);
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(10 * 1000);

            if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "fail";// 连接失败/链接失效/图片不存在
            }
            InputStream inStream = conn.getInputStream();
            int len = -1;
            while ((len = inStream.read(data)) != -1) {
                outPut.write(data, 0, len);
            }
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(outPut.toByteArray());
    }

    // 本地图片转base64

    public static String GetImageStr(String imgFile) {// 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return "data:image/jpeg;base64,"+encoder.encode(data);// 返回Base64编码过的字节数组字符串
    }

    /**
     * @Description： base64字符串转化成图片
     *
     * @param: imgStr
     * @Return:
     */

    public static String GenerateImage(String base64str, String savepath) { // 对字节数组字符串进行Base64解码并生成图片
        if (base64str == null) // 图像数据为空
            return "";
        // System.out.println("开始解码");
        base64str=base64str.replace("data:image/jpeg;base64,","");
        //base64str=base64str.replaceAll(" ", "+");
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(base64str);
            // System.out.println("解码完成");
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            // System.out.println("开始生成图片");
            // 生成jpeg图片
            String imgName =""+ System.currentTimeMillis()/1000;
//            OutputStream out = new FileOutputStream(savepath+"\\"+imgName+".jpg"); //windows 路径
            String path = savepath+"/"+imgName+".jpg";
            path = path.replaceAll("/","\\\\");// linux 路径
            OutputStream out = new FileOutputStream(path); // linux 路径
            out.write(b);
            out.flush();
            out.close();
            return path;
        } catch (Exception e) {
            return "";
        }
    }
    //base64字符串转化成图片
    public static String GenerateImageTwo(String imgStr, String savepath)
    {   //对字节数组字符串进行Base64解码并生成图片
        if (imgStr == null) //图像数据为空
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        try
        {
            //Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for(int i=0;i<b.length;++i)
            {
                if(b[i]<0)
                {//调整异常数据
                    b[i]+=256;
                }
            }
            //生成jpeg图片
            String imgFilePath = savepath;//新生成的图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return savepath;
        }
        catch (Exception e)
        {
            return null;
        }
    }

    public static List<String> getImgSrc(String htmlStr) {

        if( htmlStr == null ){

            return null;
        }

        String img = "";
        Pattern p_image;
        Matcher m_image;
        List<String> pics = new ArrayList<String>();

        String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
        m_image = p_image.matcher(htmlStr);
        while (m_image.find()) {
            img = img + "," + m_image.group();
            // Matcher m =
            // Pattern.compile("src=\"?(.*?)(\"|>|\\s+)").matcher(img); //匹配src
            Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);

            while (m.find()) {
                pics.add(m.group());
            }
        }
        return pics;
    }

    public static void main(String[] args) {

        String str = "<div><img src='ueditor/jsp/upload/image/20161117/1479366071667028023.png' title='1479366071667028023.png' alt='2016-11-16_010256.png'/><img src=\"http://47.95.209.196/easyteaching-core/mobile/teachingrecords/getUrl?path=teachrecord/2018-08-10/20180810161528fce8f644e8224841a291ea7633efb395.jpeg\" alt=\"\"></div><br><img src=\"\" alt=\"\">";

        System.out.println( getImgStr(str).get(0) );

    }
    //获取图片中所有的src
    public static List<String> getImgStr(String htmlStr) {
        List<String> list = new ArrayList<>();
        String img = "";
        Pattern p_image;
        Matcher m_image;
        // String regEx_img = "<img.*src=(.*?)[^>]*?>"; //图片链接地址
        String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
        m_image = p_image.matcher(htmlStr);
        while (m_image.find()) {
            // 得到<img />数据
            img = m_image.group();
            // 匹配<img>中的src数据
            Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
            while (m.find()) {
                htmlStr = htmlStr.replace(m.group(1),"https://image1.jpg");
                list.add(m.group(1));
            }
        }
        System.out.println(htmlStr);
        return list;
    }



}
